package im

import (
	"fmt"
	"sort"
	"crypto/sha1"
	"encoding/hex"
	"crypto/subtle"
	"github.com/astaxie/beego"
)

func FirstVerifyTest(ctrl *beego.Controller) {
	signature1 := ctrl.GetString("signature")
	if signature1 == "" {
		beego.Emergency("signature is empty")
		return
	}
	timestamp := ctrl.GetString("timestamp")
	if timestamp == "" {
		beego.Emergency("timestamp is empty")
		return
	}
	nonce := ctrl.GetString("nonce")
	if nonce == "" {
		beego.Emergency("nonce is empty")
		return
	}
	echostr := ctrl.GetString("echostr")
	if echostr == "" {
		beego.Emergency("echostr is empty")
		return
	}
	token := beego.AppConfig.String("AppletToken")
	signature2 := sign(token, timestamp, nonce)
	if !secureCompareString(signature1, signature2) {
		err := fmt.Errorf("check signature failed, input: %s, local: %s", signature1, signature2)
		beego.Emergency(err.Error())
		return
	}
	ctrl.Ctx.WriteString(echostr)
}


// 微信公众号 明文模式/URL认证 签名
func sign(token, timestamp, nonce string) (signature string) {
	strs := sort.StringSlice{token, timestamp, nonce}
	strs.Sort()
	buf := make([]byte, 0, len(token)+len(timestamp)+len(nonce))
	buf = append(buf, strs[0]...)
	buf = append(buf, strs[1]...)
	buf = append(buf, strs[2]...)
	hashsum := sha1.Sum(buf)
	return hex.EncodeToString(hashsum[:])
}

func secureCompareString(given, actual string) bool {
	if subtle.ConstantTimeEq(int32(len(given)), int32(len(actual))) == 1 {
		if subtle.ConstantTimeCompare([]byte(given), []byte(actual)) == 1 {
			return true
		}
		return false
	}
	if subtle.ConstantTimeCompare([]byte(actual), []byte(actual)) == 1 {
		return false
	}
	return false
}
